Options
All
  • Public
  • Public/Protected
  • All
Menu

Writing Custom Protocol Messages

Note

Messages refer to any level of Among Us protocol messages, be that SendOption, RootMessage, GameData or Rpc, while packets refer to any set of bytes recieved from a socket.

Writing Custom Protocol Messages

Messages in SkeldJS have been designed to be easy to both write and to register to a client or server using the PacketDecoder class.

Message Skeleton

The very basic structure of a message declaration is as follows:

class MyFavouriteMessage extends BaseMessage {
    static tag = 1 as const; // The hazel message tag.
    tag = 1 as const;

    constructor() {

    }

    static Deserialize(
        reader: HazelReader, // The message reader to read the message from.
        direction: MessageDirection, // The direction that this message is travelling in.
        decoder: PacketDecoder // The decoder that this message is going through.
    ) {
        // Should return an instance of MyFavouriteMessage
    }

    Serialize(
        writer: HazelWriter, // The message writer to write the message to.
        direction: MessageDirection,
        decoder: PacketDecoder
    ) {

    }
}

A message declaration is just a class that optionally extends one of several utility classes for standardisation, here being a very basic BaseMessage which just contains a utility for cancelling the message in some scenarios (such as if it is relayed through a server, you might want to stop this behaviour).

Otherwise, SkeldJS also contains several other classes based off of the Among Us protocol to extend:

Using the above classes rather than extending BaseMessage means that you don't need to specify the message type, since they will be set to option, root, gamedata and rpc respectfully if you extend them.

The Deserialize and Serialize methods take 3 parameters, a HazelReader or HazelWriter instance respectfully, and also both take a MessageDirection and PacketDecoder.

The Deserialize method should also return an instance of the message, while Serialize should return nothing.

Examples

Of course, SkeldJS contains plenty of examples and real-world usecases of writing messages, https://github.com/SkeldJS/SkeldJS/tree/master/packages/protocol/lib/packets.

To see an example of a custom message in the wild, I have several examples on my server implementation, Hindenburg, here

Registering and Listening to Messages

To register a custom message, you can use the PacketDecoder#register method, passing in the message class declaration itself. (Not an instance of the message)

To listen for a message to pass through the decoder, you can use the PacketDecoder#on method, passing in the message class declaration itself and a function with 3 optional parameters,

  • An instance of the message class delcaration.
  • The direction that the message is travelling in.
  • An optional parameter with the sender of the packet, if passed through the PacetkDecoder#write method

For example, you can do

const packetDecoder = new PacketDecoder;

packetDecoder.register(MyFavouriteMessage);

packetDecoder.on(MyFavouriteMessage, (message, direction, sender) => {
    console.log("Got my favourite message from %s", sender.username);
});

to register and listen for your favourite message ever.

Generated using TypeDoc